package com.yxb.config.interceptor;

import com.yxb.constant.GlobalParam;
import com.yxb.util.CHexConver;
import com.yxb.util.ReturnToClientUtil;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * @author
 */
public class GateWayInterceptor extends HandlerInterceptorAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(GateWayInterceptor.class);



    private static final String POST_METHOD = "post";
    private static final String GET_METHOD = "get";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String method = request.getMethod();
        LOGGER.info("method:[{}]", method);
        LOGGER.info("content-type:[{}]", request.getContentType() );

        if ( method.equalsIgnoreCase(GET_METHOD) ){
            return  xLinkValid(request, response);
        }

        if ( method.equalsIgnoreCase(POST_METHOD) ){
            return verifyXLinkData(request, response);
        }
        LOGGER.error("method:[{}], 方法不是 get/post", method);
        ReturnToClientUtil.responseFailParameter("method invalid", request, response);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }


    private boolean verifyXLinkData(HttpServletRequest request, HttpServletResponse response) throws IOException {

        LOGGER.info("Access-Token:->{}", request.getHeader("Access-Token"));
        String accessToken = request.getHeader("Access-Token");
        if ( !accessToken.equalsIgnoreCase(GlobalParam.TOKEN_SELF) ){
            LOGGER.error("token invalid : accessToken:[{}]", accessToken);
            ReturnToClientUtil.responseFailParameter("token值不对", request, response);
            return false;
        }
        return true;
    }


    private boolean xLinkValid(HttpServletRequest request, HttpServletResponse response) throws IOException {

        String timestampStr = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String signatureStr = request.getParameter("signature");
        String echostr = request.getParameter("echostr");
        LOGGER.info("timestamp:[{}],nonce:[{}],signature:[{}],echostr:[{}]", timestampStr, nonce, signatureStr, echostr);
        if ( StringUtils.isAnyBlank(timestampStr, nonce, signatureStr, echostr) ){
            LOGGER.error("forward data :  timestamp:[{}],nonce:[{}] error", timestampStr, nonce);
            ReturnToClientUtil.responseFailParameter("必要参数缺失", request, response);
            return false;
        }

        List<String> strList = new ArrayList<>();
        strList.add(GlobalParam.TOKEN_SELF);
        strList.add(timestampStr);
        strList.add(nonce);
        Collections.sort(strList);

        String toEncryStr = strList.get(0)+strList.get(1)+strList.get(2);
        LOGGER.info("before encry str :[{}]", toEncryStr);
        String encryStr = DigestUtils.sha1Hex(toEncryStr);
        if ( !encryStr.toUpperCase().equals(signatureStr) ){
            LOGGER.error("do encry [{}] , parameter->signature :[{}] not equals", encryStr, signatureStr);
            return false;
        }
        response.getWriter().write(echostr);
        return false;

    }

    public static String toStringHex1(String s) {
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
                        i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            // UTF-16le:Not
            s = new String(baKeyword, "utf-8");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return s;
    }

    public static void main(String[] args) throws DecoderException, UnsupportedEncodingException {
        List<String> strList = new ArrayList<>();
        strList.add("lVZbxReDGqVlCWogsciSQwHczNfKqUqU");
        strList.add("1522832219699");
        strList.add("a32a9f05-ec17-4013-8183-a7d283efae5f");

        Collections.sort(strList);

        //String str = "nonce=lVZbxReDGqVlCWogsciSQwHczNfKqUqUtimestamp=1522832219699token=a32a9f05-ec17-4013-8183-a7d283efae5f";
//        String encryStr = DigestUtils.sha1Hex(strList.get(0)+strList.get(1)+strList.get(2));
//        System.out.println(encryStr);

        //String str = "5AC4832F";
        String str = "5AC4832F04B0022C580400";
        //byte[] bytes = Hex.decodeHex(str);

        short[] bytes = CHexConver.hexStringToBytes(str);

        int b = (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3];
        int c = (bytes[4]<<8)+(bytes[5]);
        int d = (bytes[6]<<8)+(bytes[7]);
        int e = (bytes[8]<<16)+(bytes[9]<<8)+(bytes[10]);

        System.out.println(b);
        System.out.println(c);
        System.out.println(d);
        System.out.println(e);


        System.out.println(DigestUtils.md5Hex(GlobalParam.TOKEN_SELF));


        //System.out.println(merge(c,d));

        //System.out.println(( c<<8)|d );

    }
    public static int merge(int high, int low)
    {
        return (((0x000000ff & high) << 8) & 0x0000ff00) | (0x000000ff & low);
    }

//    public static int[] hexStringToBytes(String hexString) {
//        if (hexString == null || hexString.equals("")) {
//            return null;
//        }
//        hexString = hexString.toUpperCase();
//        int length = hexString.length() / 2;
//        char[] hexChars = hexString.toCharArray();
//        int [] d = new int[length];
//        for (int i = 0; i < length; i++) {
//            int pos = i * 2;
//            d[i] =  (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
//        }
//        return d;
//    }

    public static byte  charToByte(char c){
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

}
